package com.renu.jdependencyanalyser.utils;

import com.renu.jdependencyanalyser.cons.ProjectCons;
import com.renu.jdependencyanalyser.core.ProjectInfo;
import com.renu.jdependencyanalyser.data.ProjectDataCenter;
import com.renu.jdependencyanalyser.model.ClassModel;
import com.renu.jdependencyanalyser.model.MethodModel;
import com.renu.jdependencyanalyser.model.PackageModel;
import lombok.extern.slf4j.Slf4j;
import soot.Type;

import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
public class MyProjectUtil {

    public static  String projectBasePath;


    public  static  String getProjectName(){
        String[] split = projectBasePath.split(File.separator);
        return split[split.length - 1];
    }


    public static boolean isJDKClassOrBasicType(String className)  {
        // 创建一个可变的 HashSet
        Set<String> mutableSet = new HashSet<>();
        String [] basicType  = {"int","byte","short","long","double","float","boolean"};

        Set<String> immutableSet = Collections.unmodifiableSet(Arrays.stream(basicType).collect(Collectors.toSet()));
        if (className.startsWith("java.") || className.startsWith("sun.")
                || className.startsWith("com.sun.") || className.startsWith("org.omg.") || className.startsWith("org.xml.")
                || className.startsWith("org.w3c.dom") || className.startsWith("javax.") || immutableSet.contains(className))
            return true;
        return false;
    }

    public static  String replaceJDKAndProjectClsSig2SimpleSig(String className){
        int index = className.lastIndexOf(".");
        if (index == -1 ){
            return  className;
        }
        return className.substring(index+1);
        //String pckName = className.substring(0,index);
        //boolean flag = false;
        //if (className.startsWith("java.") || className.startsWith("sun.")
        //        || className.startsWith("com.sun.") || className.startsWith("org.omg.") || className.startsWith("org.xml.")
        //        || className.startsWith("org.w3c.dom") || className.startsWith("javax.") ){
        //    flag |= true;
        //}
        //if (ProjectDataCenter.projectInfo!= null){
        //    PackageModel packageModel = ProjectDataCenter.projectInfo.getOuterPckMap().get(pckName);
        //    if (packageModel!= null){
        //        flag |= true;
        //    }
        //}
        //if (flag){
        //    return  className.substring(index+1);
        //}
        //return className;
    }
    public static String type2String(Type type) {
        String string = type.toString().toString();
        return string.replace("[]","");


    }

    public static String type2String(String type) {
        return type.replace("[]","");


    }


    public static String getFieldSig(String classSig, String fieldType, String fieldName) {
        return new StringBuilder().append(classSig).append(":").append(fieldType).append(" ").append(fieldName).toString();

    }

    public static boolean isIndirOuterClass(String clsSig, ProjectInfo projectInfo,int dpth) {
        if (dpth == ProjectCons.MAX_DPTH_CLS) {
            return false;
        }
        if (MyProjectUtil.isJDKClassOrBasicType(clsSig)){
            return false;
        }
        if (projectInfo.getOuterClassMap().containsKey(clsSig)){
            return true;
        }
        ClassModel classModel = projectInfo.getClassModel(clsSig);
        String extendClsSig = classModel.getExtendClsSig();
          if (isIndirOuterClass(extendClsSig,projectInfo,dpth+1)){
              return true;
          }

        for (String s : classModel.getImplementClssSig()) {
            if (isIndirOuterClass(s,projectInfo,dpth+1)){
                return true;
            }
        }
        return false;



    }

    public static boolean isIndirOuterMethod(String methodSig, ProjectInfo projectInfo, int dpth) {
        if (dpth == ProjectCons.MAX_DPTH_MTHD){
            return false;
        }
        if (projectInfo.getBorderMethod(methodSig)!= null){
            return true;
        }
        MethodModel method = projectInfo.getMethod(methodSig);
        for (String outerMethod : method.getTgtMethods()) {
            if (isIndirOuterMethod(outerMethod,projectInfo,dpth+1)){
                return true;
            }
        }
        return false;
        
    }

    /**
     *
     * @param clsSig org.example.soot.SootOptionSet
     * @return SootOptionSet
     */
    public static String convertClsSig2ClsName(String clsSig) {
        int index  = clsSig.lastIndexOf('.');
        if (index==-1){
            return clsSig;
        }
        return clsSig.substring(index+1);
    }

    /**
     *
     * @param methosSig soot.Main::void main(java.lang.String [])
     * @return  void main(java.lang.String [])
     */
    public static String converMthdSig2MthdName(String methosSig) {
        return methosSig.substring(methosSig.indexOf("\n")+1);
    }

    /**
     *
     * @param fieldSig org.example.test.Employee:org.objectweb.asm.ClassVisitor classVisitor
     * @return
     */
    public static String convertFldsSig2FldName(String fieldSig) {
        int index= fieldSig.lastIndexOf('.');
        if (index == -1){
            index = fieldSig.lastIndexOf(':');
        }
        return fieldSig.substring(index+1);
    }

    public static String getClsSigFromMthdSig(String methodSig) {
        return methodSig.substring(0,methodSig.indexOf("::"));
    }
}
